/**
 * Copyright 2002 Cordys R&D B.V. 
 * 
 * This file is part of the Cordys .NET Connector. 
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
 /**
 *
 * @author  owarnier
 * changed by pkavuri
 */
package com.eibus.applicationconnector.ejb;

import com.eibus.xml.nom.Document;

import com.eibus.xml.nom.Node;
import com.eibus.xml.xpath.XPath;
import com.eibus.util.logger.CordysLogger;

import java.io.BufferedInputStream;
import java.io.InputStream;
import java.io.IOException;
import java.util.Hashtable;
import java.util.Map;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import static com.eibus.applicationconnector.ejb.EJBObjectMetaData.*;

 class EJBObjectMetaDataGenerator {
    
    private Hashtable metaDataObjects;
    private JarFile jarFile;
    private static Document doc;
    static CordysLogger ejbLogger = CordysLogger.getCordysLogger(EJBObjectMetaDataGenerator.class);
    static {
        doc = new Document();
    }
    /** Creates a new instance of EJBObjectMetaDataGenerator */
     EJBObjectMetaDataGenerator() {
    }
    
    /**
     * parse the ejb-jar.xml that is found in a deployable archive for EJBs<br>
     * this file is found in the META-INF diretory and contains information on the EJBs
     * deployed in this file as well as their interfaces and their names
     * @param the jarfile that contains the deployable EJBs and the ejb-jar.xml file
     */
     void parseJarFile(JarFile jarFile) {
        this.jarFile = jarFile;
        if (ejbLogger.isDebugEnabled())
        	ejbLogger.debug("entering addMetaDataToCache for jarfile:" + jarFile.getName());
        JarEntry loadedEntry = jarFile.getJarEntry("META-INF/ejb-jar.xml");
         if (metaDataObjects == null)
                metaDataObjects = new Hashtable();
		if(loadedEntry==null) 
		 {
			String fileName=jarFile.getName();
	        String pathSeperator = System.getProperty("file.separator");
			int index=fileName.lastIndexOf(pathSeperator);
	        if (ejbLogger.isWarningEnabled())
	        	ejbLogger.warn("Could not find Metabase file in the Jar :"+fileName+".");
			metaDataObjects.put(fileName.substring(index+1),fileName.substring(index+1));
			return;
		 }
        // Parse the xml to build the MetaData objects of the available EJBs
        // read the xml file into bytes
        InputStream fi = null;
        int root = 0;
        byte[] classBytes = null;
        try {
            int classSize = (int)loadedEntry.getSize();
            fi = new BufferedInputStream(jarFile.getInputStream(loadedEntry));
            classBytes = new byte[classSize];
            fi.read(classBytes);
        }
        catch (IOException ioEx) {
            if (ejbLogger.isErrorEnabled())
            	ejbLogger.error("exception",ioEx);
        }
        // ignore the exceptions (as thijs told me)
        try {
            root = doc.load(classBytes);
        }
        catch (Exception ex) {
        	if (ejbLogger.isErrorEnabled())
        		ejbLogger.error("exeption during document load ",ex);
        }
        //int[] listOfEJBs = Find.match(root,"?<ejb-name>");
        //int[] listOfEJBs = ejbnameXpath.selectElementNodes(root);
        int[] listOfEJBs = XPath.getMatchingNodes(ejbnameXpath, null, root) ;
        String ejbName = null;
        for(int i = 0;i < listOfEJBs.length;i++) {
            ejbName = Node.getData(listOfEJBs[i]);
            int parentNode = Node.getParent(listOfEJBs[i]);
            if (parentNode == 0){
            	if (ejbLogger.isWarningEnabled())
            		ejbLogger.warn("Improper or corrupted bean");
            }
            String ejbType = Node.getName(parentNode);
            if ("session".equalsIgnoreCase(ejbType) || "entity".equalsIgnoreCase(ejbType)) {
                if (ejbLogger.isDebugEnabled())
                	ejbLogger.debug("type of parent node:" + ejbType + " generate metadata");
       
            }
            else {
                if (ejbLogger.isWarningEnabled())
                	ejbLogger.warn("type of parent node:" + ejbType + " do not generate metadata");
                continue;
            }
            EJBObjectMetaData tmpMetaData = new EJBObjectMetaData();
            try {
                tmpMetaData = new EJBObjectMetaData(Node.duplicate(parentNode));
                if (ejbLogger.isDebugEnabled())
                	ejbLogger.debug("Created metadataObjects with following information"+Node.writeToString(parentNode, true));
            }
            catch(Exception e) {
            	if (ejbLogger.isErrorEnabled())
            		ejbLogger.error("exception.",e);
            }
            if (metaDataObjects == null)
                metaDataObjects = new Hashtable();
            metaDataObjects.put(ejbName, tmpMetaData);
            if (ejbLogger.isDebugEnabled())
            	ejbLogger.debug("added object to the metaDataObjects Hashtable");
        }
        if(root > 0)
        {        	
        	Node.delete(root);
        	root = 0;
        }
    } // end of parseJarFile()
    
    /**
     * Method to get the parsed objects out of this class
     */
     Map getMetaDataObjects() {
        return (Map) metaDataObjects;
    }
}
